package com.xidian.zhiancloud.service.chemicalsManagement.chemicalManager.dangerousPart;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xidian.zhiancloud.constant.DangerousManagementConstant;
import com.xidian.zhiancloud.dao.DangerousChemicalInfoMapper;
import com.xidian.zhiancloud.dto.ResultDTO;
import com.xidian.zhiancloud.enums.GeneralResponseEnums;
import com.xidian.zhiancloud.exception.CustomizeException;
import com.xidian.zhiancloud.model.DangerCategory;
import com.xidian.zhiancloud.model.DangerousChemicalInfo;
import com.xidian.zhiancloud.model.DangerousChemicalInfoChange;
import com.xidian.zhiancloud.qo.chemicalsManagement.DangerousChemicalInfoQO;
import com.xidian.zhiancloud.service.user.UserService;
import com.xidian.zhiancloud.vo.chemicalsManagement.DangerousChemicalInfoVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: Egoist
 * @Date: 2020/11/10 17:00
 */

@Service
public class DangerousChemicalInfoService extends ServiceImpl<DangerousChemicalInfoMapper, DangerousChemicalInfo>  implements IService<DangerousChemicalInfo> {

    @Autowired
    private DangerousChemicalInfoMapper dangerousChemicalInfoMapper;

    @Autowired
    private DangerCategoryService dangerCategoryService;

    @Autowired
    private DangerousChemicalInfoChangeService dangerousChemicalInfoChangeService;

    @Autowired
    private UserService userService;

    public IPage<DangerousChemicalInfoVO> getListByQueryObject(DangerousChemicalInfoQO dangerousChemicalInfoQO) {
        Page<DangerousChemicalInfoVO> page = new Page<>(dangerousChemicalInfoQO.getCurrent(), dangerousChemicalInfoQO.getSize());
        OrderItem orderItem = new OrderItem();
        orderItem.setColumn("create_time").setAsc(false);
        page.getOrders().add(orderItem);
        return dangerousChemicalInfoMapper.getListByQO(page, dangerousChemicalInfoQO);

    }

    public DangerousChemicalInfoVO getVOById(Long id) {
        DangerousChemicalInfo dangerousChemicalInfo = getById(id);
        if (dangerousChemicalInfo == null) {
            throw new CustomizeException(GeneralResponseEnums.GET_FAILED);
        }
        DangerousChemicalInfoVO dangerousChemicalInfoVO = new DangerousChemicalInfoVO();
        BeanUtils.copyProperties(dangerousChemicalInfo, dangerousChemicalInfoVO);
        DangerCategory dangerCategory = dangerCategoryService.getById(dangerousChemicalInfo.getDangerousTypeId());
        dangerousChemicalInfoVO.setDangerousType(dangerCategory == null ? "该类型已删除" : dangerCategory.getName());
        return dangerousChemicalInfoVO;
    }

    public Boolean hiddenByIds(List<Long> asList) {
        List<DangerousChemicalInfo> dangerousChemicalInfos = listByIds(asList);
        ArrayList<DangerousChemicalInfo> ans = new ArrayList<>();
        dangerousChemicalInfos.forEach(t -> {
            t.setHidden(1);
            ans.add(t);
        });
        return updateBatchById(ans);
    }

    public ResultDTO<Boolean> updateRecordById(DangerousChemicalInfo newInfo, Long userId) {
        //防止修改导致重名
        String name = newInfo.getName();
        QueryWrapper<DangerousChemicalInfo> query = new QueryWrapper<>();
        query.eq("company_id", newInfo.getCompanyId()).eq("hidden", 0);
        List<DangerousChemicalInfo> infoList = list(query);
        for (DangerousChemicalInfo chemicalInfo : infoList) {
            //如果修改记录与库内记录的品名相同 并且 修改记录与库内记录不是同一条时 发生重名错误
            if (name != null && name.equals(chemicalInfo.getName()) &&
                    !chemicalInfo.getId().equals(newInfo.getId())) {

                newInfo.setName(null);
                return ResultDTO.errorOf(-1, name + " 已存在!");
            }
        }
        //创建变更记录
        String changeInfo = getChangeInfo(newInfo, userId);
        if (!changeInfo.equals("")) {
            DangerousChemicalInfoChange dangerousChemicalInfoChange = new DangerousChemicalInfoChange();
            dangerousChemicalInfoChange.setInfoId(newInfo.getId());
            dangerousChemicalInfoChange.setInfoType(changeInfo);
            dangerousChemicalInfoChange.setChangeTime(new Date(System.currentTimeMillis()));
            dangerousChemicalInfoChange.setChangeUserId(userId);
            dangerousChemicalInfoChangeService.save(dangerousChemicalInfoChange);
        }

        return ResultDTO.successOf(updateById(newInfo), GeneralResponseEnums.SUCCESS);
    }

    private String getChangeInfo(DangerousChemicalInfo newInfo, Long userId) {

        DangerousChemicalInfo oldInfo = getById(newInfo.getId());
        List<String> str1 = Arrays.asList("Name", "Alias", "Code", "MolFormula", "CasNum", "MolPic");
        List<String> str2 = Arrays.asList("Unit");
        List<String> str3 = Arrays.asList("MelPoint", "BoiPoint", "FlaPoint", "Density", "WatSol", "PropertyDes");
        List<String> str4 = Arrays.asList("DangerousTypeId", "CtrlMeasures", "DangerSigns", "Remark");

        StringBuffer buffer = new StringBuffer();
        String userName = userService.getById(userId).getName();
        buffer.append(userName + " ");

        //查询修改对象中不为空的字段
        List<String> newList = getValue(newInfo);
        List<String> oldList = getValue(oldInfo);
        int flag = 0;
        for (String s : newList) {
            try {
                Method method = newInfo.getClass().getMethod("get" + s);
                String newField = method.invoke(newInfo).toString();
                String oldField = "";
                if (oldList.contains(s)) {
                    oldField = method.invoke(oldInfo).toString();
                }
                //该字段不内容不同时，也就是内容被修改时
                if (!newField.equals(oldField)){
                    if (str1.contains(s) && flag != 1) {
                        flag = 1;
                        buffer.append("更改了基本信息 ");
                    } else if (str2.contains(s) && flag != 2) {
                        flag = 2;
                        buffer.append("更改了计量信息 ");
                    } else if (str3.contains(s) && flag != 3) {
                        flag = 3;
                        buffer.append("更改了物理化学性质 ");
                    } else if (str4.contains(s) && flag != 4) {
                        flag = 4;
                        buffer.append("更改了安全信息 ");
                    }
                }

            } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return flag == 0 ? "" : buffer.toString();
    }


    private List<String> getValue(Object object){
        List<String> list = new ArrayList();
        Field[] field = object.getClass().getDeclaredFields();
        for (Field item : field) {
            String name = item.getName();

            name = name.substring(0, 1).toUpperCase() + name.substring(1);

            Method m;
            Object value;
            try {
                m = object.getClass().getMethod("get" + name);
                value = m.invoke(object);
                if (value != null) {
                    list.add(name);
                }
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
        }
        return list;
    }

    public List<DangerousChemicalInfoChange> getChangeRecord(Long id) {
        LambdaQueryWrapper<DangerousChemicalInfoChange> query = Wrappers.<DangerousChemicalInfoChange>lambdaQuery();
        query.eq(DangerousChemicalInfoChange::getInfoId, id);
        return dangerousChemicalInfoChangeService.list(query);
    }

    public ResultDTO<Boolean> saveInfo(DangerousChemicalInfo dangerousChemicalInfo) {
        //品名重复检查，一个租户下没有被隐藏的记录的品名不能重复
        QueryWrapper<DangerousChemicalInfo> query = new QueryWrapper<>();
        query.eq("company_id", dangerousChemicalInfo.getCompanyId()).eq("hidden", 0);
        List<DangerousChemicalInfo> list = list(query);
        if (list != null) {
            for (DangerousChemicalInfo chemicalInfo : list) {
                if (chemicalInfo.getName().equals(dangerousChemicalInfo.getName())) {
                    return ResultDTO.errorOf(-1, dangerousChemicalInfo.getName() + " 已存在!");
                }
            }
        }
        return ResultDTO.successOf(save(dangerousChemicalInfo), GeneralResponseEnums.SUCCESS);
    }

    public Map<Long, String> getChemicalNameList(Long companyId) {
        LambdaQueryWrapper<DangerousChemicalInfo> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(DangerousChemicalInfo::getCompanyId, companyId);
        queryWrapper.eq(DangerousChemicalInfo::getHidden, 0);
        List<DangerousChemicalInfo> list = dangerousChemicalInfoMapper.selectList(queryWrapper);
        return list.stream().collect(Collectors.toMap(DangerousChemicalInfo::getId, DangerousChemicalInfo::getName));
    }

    public Long getChemicalInfoIdByName(String name) {
        QueryWrapper<DangerousChemicalInfo> query = new QueryWrapper<DangerousChemicalInfo>();
        query.eq("name", name);
        return getOne(query).getId();
    }

    public String getUnitByName(String name) {
        Long id = getChemicalInfoIdByName(name);
        DangerousChemicalInfo info = getById(id);
        return DangerousManagementConstant.QuantityUnit.get(info.getUnit());
    }
}
